package com.xinyue.game.service.framwork.context;

import com.xinyue.cross.server.server.ServerResponseService;
import com.xinyue.game.message.GameServerMessageModel;
import com.xinyue.game.message.GameServerRequestHeader;
import com.xinyue.game.message.GameServerResponseHeader;
import com.xinyue.game.service.framwork.common.GameServerException;
import com.xinyue.game.service.framwork.mapping.GameHandlerMappingManager;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GameUserChannel {
    private static Logger logger = LoggerFactory.getLogger(GameUserChannel.class);
    private EventLoop executor;
    private String gatewayId;

    public GameUserChannel(EventLoop executor, String gatewayId) {
        this.executor = executor;
        this.gatewayId = gatewayId;
    }

    public void handlerRequestMessage(GameServerMessageModel<GameServerRequestHeader> msg, ChannelHandlerContext ctx) {
        if (executor.inEventLoop()) {
            this.handlerRequestMessage0(msg, ctx);
        } else {
            executor.execute(() -> {
                handlerRequestMessage0(msg, ctx);
            });
        }
    }

    /**
     * 接收网关转发过来的客户端请求，并将请求映射到对应的处理类
     *
     * @param msg
     */
    private void handlerRequestMessage0(GameServerMessageModel<GameServerRequestHeader> msg, ChannelHandlerContext ctx) {
        try {
            // 根据requestUri 找到对应的处理参数类，用调用处理方法
            GameUserChannelContext uct = new GameUserChannelContext(ctx, msg, this);
            GameHandlerMappingManager gameHandlerMappingManager = GameHandlerMappingManager.getInstance();
            gameHandlerMappingManager.callMethod(uct);
        } catch (Throwable e) {
            handlerGameLogicException(e, msg.getHeader(), ctx);
        }
    }

    private boolean handlerGameLogicException(Throwable e, GameServerRequestHeader requestHeader, ChannelHandlerContext ctx) {
        logger.error("处理业务请求异常,requestHeader: {}", requestHeader, e);
        boolean flag = (e instanceof GameServerException);
        if (flag) {
            // 直接返回错误
            GameServerException ge = (GameServerException) e;
            GameServerMessageModel<GameServerResponseHeader> responseModel = ServerResponseService.createResponseModel(requestHeader, ge.getErrorCode(), ge.getErrorDesc());
            ctx.writeAndFlush(responseModel);
        } else {
            GameServerMessageModel<GameServerResponseHeader> responseModel = ServerResponseService.createResponseModel(requestHeader, -1, "服务器错误:" + e.getMessage());
            ctx.writeAndFlush(responseModel);
        }
        return flag;
    }

    /**
     * 返回网关的连接id，用于消息推送时，查找对应的网关连接
     *
     * @return
     */
    public String getGatewayId() {
        return gatewayId;
    }
}
